#pragma once

#include "../RHIResource.h"


class RHISemaphore : public RHIResource
{
	struct BuilderDetails {

		VkSemaphoreType semaphoreType;

		uint32 count;
		
		VkPipelineStageFlags waitDstStage;

		bool isSignaled;

		BuilderDetails();
	};

public:

	class Builder : public BuilderBase<BuilderDetails> {
		friend struct BuilderDetails;
	public:
		Builder() noexcept;
		Builder(Builder const& rhs) noexcept;
		Builder(Builder&& rhs) noexcept;
		~Builder() noexcept;
		Builder& operator=(Builder const& rhs) noexcept;
		Builder& operator=(Builder&& rhs) noexcept;

		Builder& SetSemaphoreType(VkSemaphoreType semaphoreType) noexcept;

		Builder& SetCount(uint32 count) noexcept;

		// If use this semaphore for wait on submit, which pipeline stage should pause before signaled
		Builder& SetWaitDstStage(VkPipelineStageFlags waitDstStage) noexcept;

		Builder& SetSignaled(bool isSignaled) noexcept;

		RefCountPtr<RHISemaphore> Build();
		RefCountPtr<RHISemaphore> Build(RenderProcess* process, const std::string& name);

	private:

		friend class RHISemaphore;
	};

	RHISemaphore(BuilderDetails& builderDetails);

	virtual void ReleaseResource() override;

	virtual ~RHISemaphore();

public:

	VkSemaphore GetSemaphore(uint32 index = UINT32_MAX) const;

	VkPipelineStageFlags GetWaitDstStage() const;

protected:

	std::vector<VkSemaphore> mSemaphores;

	VkPipelineStageFlags mWaitDstStage;
};